
using System;
using System.Windows;
using Boilen.Freezables;
using Boilen.Guards;


namespace Boilen.Primitives.CodeGeneration
{

#if SL3_0
    using Freezable = System.Windows.FrameworkElement;
#endif

    partial class SourceFreezableBase : Freezable
#if SL3_0
        ,
        IFreezable
#endif
    {

        /// <summary>
        /// Identifies the <see cref='P:Boilen.Primitives.CodeGeneration.SourceFreezableBase.State'/> dependency property.
        /// </summary>
        /// <returns>
        /// The identifier for the <see cref='P:Boilen.Primitives.CodeGeneration.SourceFreezableBase.State'/> dependency property.
        /// </returns>
        public static readonly DependencyProperty StateProperty;


        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "AUTOGEN: Initializes static members.")]
        static SourceFreezableBase()
        {
#if SL3_0
            SourceFreezableBase.StateProperty = DependencyProperty.Register(
                "State", typeof(int), typeof(SourceFreezableBase),
                new PropertyMetadata(
                    default(int),
                    new PropertyChangedCallback(SourceFreezableBase.StateChangedShim)
                )
            );
#else
            SourceFreezableBase.StateProperty = DependencyProperty.Register(
                "State", typeof(int), typeof(SourceFreezableBase),
                new PropertyMetadata(
                    default(int)
                )
            );
#endif

            SourceFreezableBase.InitializeType();
        }

        static partial void InitializeType();


        /// <include file='prefix/SourceFreezableBase.xml' path='/doc/member[@name="State"]/*' />
        public int State
        {
            get { return (int)this.GetValue(SourceFreezableBase.StateProperty); }
            set { this.SetValue(SourceFreezableBase.StateProperty, value); }
        }

#if SL3_0
        private bool _privateBackingFieldForProperty_State_RevertingDependencyPropertyChange_SL;

        private static void StateChangedShim(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            SourceFreezableBase self = (SourceFreezableBase)d;
            if (self._privateBackingFieldForProperty_State_RevertingDependencyPropertyChange_SL)
                return;

            if (self.IsFrozen)
            {
                self._privateBackingFieldForProperty_State_RevertingDependencyPropertyChange_SL = true;
                self.SetValue(SourceFreezableBase.StateProperty, e.OldValue);
                self._privateBackingFieldForProperty_State_RevertingDependencyPropertyChange_SL = false;
                self.GuardValue("this").Satisfies(false, "Cannot set a property on object '{0}' because it is in a read-only state.", self);
            }

            self.OnSubpropertyChanged();
        }
#endif


#if SL3_0
        #region IFreezable Members

        private bool _privateBackingFieldForProperty_IsFrozen;
        private EventHandler _privateBackingFieldForEvent_SubpropertyChanged;

        /// <summary>
        /// Gets a value that indicates whether the object is currently modifiable.
        /// </summary>
        /// <returns>
        /// <see langword='true'/> if the object is frozen and cannot be modified; <see langword='false'/> if the object can be modified.
        /// </returns>
        public bool IsFrozen
        {
            get { return this._privateBackingFieldForProperty_IsFrozen; }
        }

        /// <summary>
        /// Occurs when a property changes.
        /// </summary>
        event EventHandler IFreezable.SubpropertyChanged
        {
            add { if (!this.IsFrozen) { this._privateBackingFieldForEvent_SubpropertyChanged += value; } }
            remove { if (!this.IsFrozen) { this._privateBackingFieldForEvent_SubpropertyChanged -= value; } }
        }

        /// <summary>
        /// Makes the current object unmodifiable and sets its <see cref="IsFrozen" /> property to <see langword='true'/>.
        /// </summary>
        public void Freeze()
        {
            if (!this.IsFrozen)
            {
                this.OnFreeze();
                this.FreezeProperties();
                this._privateBackingFieldForEvent_SubpropertyChanged = null;
                this._privateBackingFieldForProperty_IsFrozen = true;
            }
        }

        partial void OnFreeze();

        /// <summary>
        /// Calls <see cref='IFreezable.Freeze'/> on every freezable property.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Implemented as part of SL Freezable pattern.")]
        protected virtual void FreezeProperties()
        {
        }

        /// <summary>
        /// Raises the SubpropertyChanged event.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Supports the SubpropertyChanged event.")]
        protected void OnSubpropertyChanged()
        {
            EventHandler handler = this._privateBackingFieldForEvent_SubpropertyChanged;
            if (!object.ReferenceEquals(handler, null))
            {
                handler(this, EventArgs.Empty);
            }
        }

        #endregion
#else
        #region Freezable Members

        /// <inheritdoc cref='System.Windows.Freezable.CreateInstanceCore'/>
        protected override Freezable CreateInstanceCore()
        {
            return new SourceFreezableBase();
        }

        #endregion
#endif

    }

}
